package com.my.study.aqs;

import com.my.study.utils.ThreadUtil;
import lombok.extern.slf4j.Slf4j;

import java.util.concurrent.locks.StampedLock;

/**
 * @author Carlos
 * @version 1.0
 * @Description 数据容器
 * @date 2021/6/19 9:14
 **/
@Slf4j(topic = "c.DataContainerStamped")
public class DataContainerStamped {
    private int data;
    private final StampedLock lock = new StampedLock();


    public DataContainerStamped(int data) {
        this.data = data;
    }

    public int read(int realTime) {
        long stamp = lock.tryOptimisticRead();
        log.debug("optimistic read lock {}", stamp);
        ThreadUtil.sleep(realTime);
        if (lock.validate(stamp)) {
            log.debug("read finish...{}", stamp);
            return data;
        }

        // 锁升级
        log.debug("update to read lock...{}", stamp);
        try {
            stamp = lock.readLock();
            log.debug("read lock {}", stamp);
            ThreadUtil.sleep(realTime);
            log.debug("read finish...{}", stamp);
            return data;
        } finally {
            log.debug("read unlock...{}", stamp);
            lock.unlockRead(stamp);
        }
    }


    public void write(int data) {
        long stamp = lock.writeLock();
        log.debug("write lock {}", stamp);

        try {
            ThreadUtil.sleep(2);
            this.data = data;
        } finally {
            log.debug("write lock {}", stamp);
            lock.unlockWrite(stamp);
        }

    }
}
